package com.wash.shoes.task;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.wash.shoes.domain.dy.model.DyBookNotifyCallBackVo;
import com.wash.shoes.domain.dy.request.DyBookRequest;
import com.wash.shoes.domain.dy.request.DyConstant;
import com.wash.shoes.domain.order.PayNotifyOrderComponent;
import com.wash.shoes.entity.OrderGoodPo;
import com.wash.shoes.entity.OrderPo;
import com.wash.shoes.queue.RedisDelayQueue;
import com.wash.shoes.request.DyDelayedOrderRecord;
import com.wash.shoes.service.OrderGoodService;
import com.wash.shoes.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class DyDelayedOrderWorker extends Thread implements InitializingBean {

    private final DyBookRequest dyBookRequest;

    private final OrderService orderService;

    private PayNotifyOrderComponent payNotifyOrderComponent;

    public DyDelayedOrderWorker(DyBookRequest dyBookRequest, OrderService orderService, PayNotifyOrderComponent payNotifyOrderComponent, RedissonClient redissonClient, OrderGoodService orderGoodService) {
        super("DyDelayedOrderWorker");
        this.dyBookRequest = dyBookRequest;
        this.redissonClient = redissonClient;
        this.payNotifyOrderComponent = payNotifyOrderComponent;
        this.orderService = orderService;
        this.orderGoodService = orderGoodService;
    }

    private OrderGoodService orderGoodService;

    @Override
    public void run() {

        while (true) {
            try {
                DyDelayedOrderRecord dyDelayedOrderRecord = DyBookRequest.CREATE_BOOK_DELAY_QUEUE.take();
                //1.调用创建预约单接口
//            dyBookRequest.postRequest(DyConstant.CREATE_BOOK_POST,dyDelayedOrderRecord.getCreateBookDto(),dyDelayedOrderRecord.getAccountId());
                log.info("DyDelayedOrderWorker createBookPost, orderId:{} orderNo:{}  ,record:{},delayed queue size :{}", dyDelayedOrderRecord.getOrderId(), dyDelayedOrderRecord.getOrderNo(), dyDelayedOrderRecord, DyBookRequest.CREATE_BOOK_DELAY_QUEUE.size());
                String bookId = null, errorCode = null;
                OrderPo orderPo = orderService.getById(dyDelayedOrderRecord.getOrderId());

                long noBookCount = orderGoodService.count(new LambdaQueryWrapper<OrderGoodPo>().eq(OrderGoodPo::getOrderId, dyDelayedOrderRecord.getOrderId()).isNull(OrderGoodPo::getDyBookId));
                //表示已经预约成功了就不处理
                if ("0".equals(orderPo.getDyBookCode()) && noBookCount == 0) {
                    continue;
                }
                log.info("DyDelayedOrderWorker createBookPost, orderId:{}, orderNo:{}  ,record:{},retryCount:{}", dyDelayedOrderRecord.getOrderId(), dyDelayedOrderRecord.getOrderNo(), dyDelayedOrderRecord, dyDelayedOrderRecord.getRetryCount());
                String result = dyBookRequest.postRequest(DyConstant.CREATE_BOOK_POST, dyDelayedOrderRecord.getCreateBookDto(), dyDelayedOrderRecord.getAccountId());
                log.info("DyDelayedOrderWorker createBookPost , orderId:{} result:{}", dyDelayedOrderRecord.getOrderId(), result);
                JSONObject resultObj = JSONObject.parseObject(result);
                bookId = resultObj.getJSONObject("data").getString("book_id");
                // 预约的结果记录到数据库
                errorCode = resultObj.getJSONObject("data").getString("error_code");
                //如果不成功重新放入队列
                if (!"0".equals(errorCode)) {
                    log.info("dy create book post errorCode is:{} , orderId:{}, will put delayed queue. orderNo:{}", errorCode, dyDelayedOrderRecord.getOrderId(), dyDelayedOrderRecord.getOrderNo());
                    if (dyDelayedOrderRecord.getRetryCount() < 3) {
                        //刷新一次外部单号
                        dyDelayedOrderRecord.refreshOutNo();
                        int count = dyDelayedOrderRecord.getRetryCount() + 1;
                        DyDelayedOrderRecord dyDelayedOrderRecord1 = new DyDelayedOrderRecord(dyDelayedOrderRecord.getCreateBookDto(), dyDelayedOrderRecord.getAccountId(), TimeUnit.SECONDS.toMillis(1), dyDelayedOrderRecord.getOrderNo(), dyDelayedOrderRecord.getOrderId(), count, dyDelayedOrderRecord.getItemOrderId());
                        DyBookRequest.CREATE_BOOK_DELAY_QUEUE.add(dyDelayedOrderRecord1);
                    } else {
                        log.info("dy create book post errorCode is:{} , orderId:{},will not put delayed queue. orderNo:{},orderId:{}", errorCode, dyDelayedOrderRecord.getOrderId(), dyDelayedOrderRecord.getOrderNo(), dyDelayedOrderRecord.getOrderId());
                    }
                }
                //2.设置order表上的     orderPo.setDyBookId(bookId);
                //        orderPo.setDyBookCode(errorCode);

                orderPo.setDyBookId(bookId);
                orderPo.setDyBookCode(errorCode);
                orderService.updateById(orderPo);

                //4.设置order_good表上的     orderGoodPo.setDyBookId(bookId);
                if (Objects.nonNull(dyDelayedOrderRecord.getItemOrderId())) {
                    orderGoodService.update(new LambdaUpdateWrapper<OrderGoodPo>()
                            .set(OrderGoodPo::getDyBookId, bookId).set(OrderGoodPo::getDyBookCode, errorCode)
                            .eq(OrderGoodPo::getItemOrderId, dyDelayedOrderRecord.getItemOrderId()));
                }

                //3.开发者可调用该接口通知开放平台预约接单结果
                if (StringUtils.isNotEmpty(bookId)) {
                    log.info("DyDelayedOrderWorker bookResultCallback.orderId:{}, orderNo:{}  ,record:{}", dyDelayedOrderRecord.getOrderId(), dyDelayedOrderRecord.getOrderNo(), dyDelayedOrderRecord);
//                    dyBookRequest.bookResultCallback(orderPo);
                    //放入预下单接口回调队列
                    RQueue<String> delayQueue = redissonClient.getQueue(RedisDelayQueue.BOOKING_RESULT_CALLBACK_QUEUE);
                    RDelayedQueue<String> queue = redissonClient.getDelayedQueue(delayQueue);

                    DyBookNotifyCallBackVo dyBookNotifyCallBackVo = new DyBookNotifyCallBackVo();
                    dyBookNotifyCallBackVo.setOrderId(orderPo.getId());
                    dyBookNotifyCallBackVo.setItemOrderId(dyDelayedOrderRecord.getItemOrderId());
                    dyBookNotifyCallBackVo.setRetryCount(0);
                    //放入队列去执行预约回调确认
                    queue.offer(JSONUtil.toJsonStr(dyBookNotifyCallBackVo), 3, TimeUnit.SECONDS);
                    log.info("DyDelayedOrderWorker bookResultCallback.orderId:{},  orderNo:{}  ,record:{} , end.", dyDelayedOrderRecord.getOrderId(), dyDelayedOrderRecord.getOrderNo(), dyDelayedOrderRecord);
                }

                long noBookCount1 = orderGoodService.count(new LambdaQueryWrapper<OrderGoodPo>().eq(OrderGoodPo::getOrderId, dyDelayedOrderRecord.getOrderId()).isNull(OrderGoodPo::getDyBookId));
                // 如果抖音的预约成功就开始处理物流信息,并且商品单全部预约完成
                if ("0".equals(orderPo.getDyBookCode()) && noBookCount1 == 0) {
                    log.info("抖音的预约成功处理物流信息:{}", orderPo);
                    payNotifyOrderComponent.process(orderPo);
                }
                //bookResultCallback
            } catch (Exception e) {
                log.error("DyDelayedOrderWorker error", e);
            }
        }
    }

    private RedissonClient redissonClient;

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("DyDelayedOrderWorker start");
        start();
        log.info("DyDelayedOrderWorker start end");
    }
}
